<!-- Picker 选择器 -->
<template>
	<view>
		<view class="select" @click="$attrs.disabled ? '' : show.value = true "
			:style="$attrs.disabled ? 'background-color: rgb(245, 247, 250)' : ''">
			<view class="p-l-5 textmp-1">
				{{selectDictLabel(...options,fieldValue,',',{ label: 'label',value: 'value'}) || fieldValue || '请选择' + ( $attrs?.label ?? '') }}
			</view>
		</view>

		<u-picker closeOnClickOverlay :show="show" :columns="options" @cancel="show=false" @close="show=false"
			@confirm="selectChange" keyName="label" :defaultIndex="pickerDefault(...options, fieldValue, 'value')"
			v-bind="$attrs"></u-picker>
	</view>
</template>

<script setup>
	// API_HOST
	import {
		API_HOST
	} from '@/config';
	// axios
	import axios from '@u/axios';
	import _camelCase from 'lodash/camelCase';

	const emits = defineEmits(['update:modelValue', 'getLabel', 'getRow']);
	/***
	 * 参数属性
	 * @property {Object[]} modelValue 默认值
	 * @property {list[]} list 下拉列表数据
	 * @property {Boolean} needAll 是否需要全部选项，默认为false
	 * @property {Object} fillType 数据格式默认为{ label: 'dictLabel', value: 'dictValue' }
	 * @property {String} type store.dispatch的方法名,兼容'GETdeptTree'/'deptTree'/'dept_tree'三种方式
	 * @property {String，Function} api 数据请求地址，默认请求为·GET·方式，支持传递url地址、api请求方法两种
	 * @property {String} url  高级搜索传递的请求地址
	 * @property {Boolean} original 是否保留原始数据，默认为false
	 */
	const props = defineProps({
		modelValue: {},
		list: {
			type: Array,
			default: () => []
		},
		needAll: {
			type: Boolean,
			default: false
		},
		fileType: {
			type: Object,
			default: () => ({
				label: 'dictLabel',
				value: 'dictValue'
			})
		},
		type: {
			type: String,
			default: ''
		},
		api: {
			type: [String, Function],
			default: ''
		},
		url: {
			type: String,
			default: ''
		},
		original: {
			type: Boolean,
			default: false
		}
	});


	const show = ref(false),
		options = ref([]),
		fieldValue = computed({
			get() {
				if (typeof props.modelValue === 'number') return `${props.modelValue}`;
				return props.modelValue;
			},
			set(val) {
				emits('update:modelValue', val);
			}
		}),
		dictType = computed(() =>
			props.type ? (props.type?.startsWith?.('GET') ? props.type : `GET${_camelCase(props.type)}`) : ''
		);

	watch(
		() => props.list,
		(val) => {
			if (Array.isArray(val)) initialization(val);
		}, {
			deep: true,
			immediate: true
		}
	);

	watch(
		() => $store?.dict[unref(dictType)?.replace('GET', '')] || $store?.com[unref(dictType)?.replace('GET', '')],
		(val) => {
			if (unref(dictType)) initialization(val);
		}, {
			deep: true,
			immediate: true
		}
	);

	watch(
		() => props.api,
		(val) => {
			if (val) {
				if (typeof val === 'string') {
					axios({
						method: 'get',
						url: API_HOST + val
					}).then((res) => {
						initialization(res.data || []);
					});
				}
				if (typeof val === 'function') {
					val().then((res) => {
						initialization(res.data || []);
					});
				}
			}
		}, {
			immediate: true
		}
	);

	watch(
		() => props.url,
		(val) => {
			if (val) {
				axios({
					method: 'get',
					url: API_HOST + val
				}).then((res) => {
					initialization(res.data);
				});
			}
		}, {
			immediate: true
		}
	);
	watch(
		() => dictType.value,
		(val) => {
			if (val) initFn();
		}, {
			immediate: true
		}
	);

	/**
	 * 获取选中的label
	 * 获取选中的对象值
	 * @param {*} val
	 */
	function selectChange(e) {
		const val = e.value[0];

		emits("update:modelValue", val?.value);
		emits('getLabel', val?.label);
		emits('getRow', val);
		show.value = false;
	}
	/**
	 * 数据处理
	 * @param {[]} data 原始数据
	 * @param {} fileType 处理{ label: 'dictLabel', value: 'dictValue' }对象
	 */
	function fileTypeFn(data, fileType = props.fileType) {
		return data.map((val) => {
			const obj = {
				label: val[fileType.label],
				value: val[fileType.value],
				disabled: val[fileType.disabled] || false
			};
			if (props.original) {
				return {
					...obj,
					...val
				};
			} else {
				return obj;
			}
		});
	}
	/**
	 * 添加全部选项
	 * @param {*} data 原始数据
	 */
	function needAllFn(data) {
		const num = JSON.stringify(data).includes(JSON.stringify({
			label: '全部',
			value: ''
		}));
		if (!num) data.unshift({
			label: '全部',
			value: ''
		});
		return data;
	}

	function initialization(list = props.list) {
		options.value = fileTypeFn(list);
		if (props.needAll) options.value = needAllFn(options.value);
	}

	// 初始化执行逻辑
	function initFn() {
		if (unref(dictType)) {
			const dictTypeFn = $store?.dict[unref(dictType)] || $store?.com[unref(dictType)];
			if (isFunction(dictTypeFn)) {
				dictTypeFn();
			} else {
				throw new Error('type 全局数据传入，但无对应执行方法！');
			}
		} else {
			initialization();
		}
	}
</script>

<style scoped lang="scss">
	.select {
		padding: 10rpx;
		border: 2rpx solid #e5e5e5;
		border-radius: 8rpx;
	}
</style>